﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel.Channels;
using System.ServiceModel;
using WcfContrib.Extensions;

namespace WcfContrib.Errors
{
    /// <summary>
    /// Represents an activation context used for error handling
    /// </summary>
    public sealed class ActivationErrorContext
    {
        /// <summary>
        /// Gets the security context.
        /// </summary>
        /// <value>The security context.</value>
        public ServiceSecurityContext SecurityContext { get; internal set; }

        /// <summary>
        /// Gets or sets the request message.
        /// </summary>
        /// <value>The request message.</value>
        public Message RequestMessage { get; internal set; }
        /// <summary>
        /// Gets the operation parameter values.
        /// </summary>
        /// <value>The parameters.</value>
        public object[] Parameters { get; internal set; }
        /// <summary>
        /// Gets the operation action.
        /// </summary>
        /// <value>The action.</value>
        public string Action { get; internal set; }
        /// <summary>
        /// Gets the name of the identity assoicated with the claim identity source.
        /// </summary>
        /// <value>The name of the identity.</value>
        public string IdentityName { get; internal set; }

        /// <summary>
        /// Gets the type of the service.
        /// </summary>
        /// <value>The type of the service.</value>
        public Type ServiceType { get; internal set; }
        /// <summary>
        /// Gets the name of the service.
        /// </summary>
        /// <value>The name of the service.</value>
        public string ServiceName { get; internal set; }
        /// <summary>
        /// Gets the service namespace.
        /// </summary>
        /// <value>The service namespace.</value>
        public string ServiceNamespace { get; internal set; }

        internal MessageBuffer MessageBuffer { get; set; }
        
        internal void CreateMessageCopy()
        {
            if (MessageBuffer != null)
            {
                CloseMessage();

                RequestMessage = MessageBuffer.CreateMessage();
            }
        }

        internal void CloseMessage()
        {
            if (RequestMessage != null && RequestMessage.State != MessageState.Closed)
            {
                try
                {
                    RequestMessage.Close();
                }
                catch { }
            }
        }
    }

    /// <summary>
    /// Represents an interface for handling error context information
    /// </summary>
    public interface IErrorContextHandler
    {
        /// <summary>
        /// Handles the error
        /// </summary>
        /// <param name="error">The error</param>
        /// <param name="errorContext">The activation error context</param>
        void HandleError(Exception error, ActivationErrorContext errorContext);

        /// <summary>
        /// Gets the required message access by the handler.
        /// </summary>
        /// <value>The required message access.</value>
        MessageAccessMode RequiredMessageAccess { get; }
    }
}
